# -*- coding: utf-8 -*-
"""
Created on 2024/8/23 16:42
@author: 江中新
"""
from curl_cffi import requests
import time
from loguru import logger
import execjs
import re
import random
import base64
import json
from concurrent.futures import ProcessPoolExecutor



class Geetest:
    def __init__(self):
        self.ctx = None
        self.token_ym = input("请输入token_ym: ")
        self._headers = {
            'Content-Type': 'application/json'
        }
        self.headers = {
            "Accept": "*/*",
            "Accept-Language": "zh-CN,zh;q=0.9",
            "Cache-Control": "no-cache",
            "Connection": "keep-alive",
            "Pragma": "no-cache",
            "Referer": "https://www.geetest.com/",
            "Sec-Fetch-Dest": "script",
            "Sec-Fetch-Mode": "no-cors",
            "Sec-Fetch-Site": "cross-site",
            "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
                          "Chrome/119.0.0.0 Safari/537.36",
            "sec-ch-ua": "^\\^Google",
            "sec-ch-ua-mobile": "?0",
            "sec-ch-ua-platform": "^\\^Windows^^"
        }

    def read_js(self):
        with open('./start.js', 'r', encoding='utf-8') as f:
            self.ctx = execjs.compile(f.read())
        logger.success("js读取成功")

    def register_page(self):
        params = {
            "t": str(int(time.time() * 1000))
        }
        response = requests.get('https://www.geetest.com/demo/gt/register-click-official', headers=self.headers,
                                params=params)
        gt = re.findall(r'"gt":"(.*?)"', response.text)[0]
        challenge = re.findall(r'"challenge":"(.*?)"', response.text)[0]
        # logger.debug(f"gt: {gt}, challenge: {challenge}")
        return gt, challenge

    def gettype(self, gt):
        params = {
            "gt": gt,
            "callback": "geetest_" + str(int(time.time() * 1000))
        }
        response = requests.get('https://api.geetest.com/gettype.php', headers=self.headers, params=params)
        # logger.info(f"type: {response.text}")

    def getPhp(self, gt, challenge):
        params = {
            "gt": gt,
            "challenge": challenge,
            "lang": "zh-cn",
            "pt": "0",
            "client_type": "web",
            "w": "",
            "callback": "geetest_" + str(int(time.time() * 1000))
        }
        time.sleep(random.randint(1, 2))
        response = requests.get('https://api.geevisit.com/ajax.php', headers=self.headers, params=params)
        # logger.info(f"php: {response.text}")

    def getAjax(self, gt, challenge):
        w2 = self.get_w2(gt, challenge)
        params = {
            "gt": gt,
            "challenge": challenge,
            "lang": "zh-cn",
            "pt": "0",
            "client_type": "web",
            "w": w2,
            "callback": "geetest_" + str(int(time.time() * 1000))
        }
        res1 = requests.get('https://api.geevisit.com/ajax.php', params=params, headers=self.headers).content.decode()
        logger.info('第二次请求返回的内容: {}'.format(res1))

    def get_w2(self, gt, challenge):
        """
        :param gt:
        :param challenge:
        """
        w2 = self.ctx.call('getW2', gt, challenge)
        # logger.info(f"w2: {w2}")
        return w2

    def get_php_Second(self, gt, challenge):
        """
        :param gt:
        :param challenge:
        """
        params = {
            "is_next": "true",
            "type": "click3",
            "gt": gt,
            "challenge": challenge,
            "lang": "zh-cn",
            "https": "true",
            "protocol": "https://",
            "offline": "false",
            "product": "float",
            "api_server": "api.geevisit.com",
            "isPC": "true",
            "autoReset": "true",
            "width": "100%",
            "callback": "geetest_" + str(int(time.time() * 1000))
        }
        # time.sleep(random.random())
        response = requests.get('https://api.geevisit.com/get.php', headers=self.headers, params=params)
        ccStr = re.findall(r'"c": \[(.*?)\]', response.text)[0]
        cc = list(map(int, ccStr.split(',')))
        ss = re.findall(r'"s": "(.*?)",', response.text)[0]
        pic = re.findall(r'"pic": "(.*?)",', response.text)[0]
        img_res = requests.get('https://static.geetest.com' + pic, headers=self.headers)
        open('./点选.png', 'wb').write(img_res.content)
        xy = self.click_verify(img_res.content)
        # logger.debug(f"cc: {cc}, ss: {ss}, pic: {pic}, 坐标: {xy}")
        click_true_str = self.geetest_click(xy)
        w3 = self.ctx.call('getW3', gt, challenge, pic, cc, ss, click_true_str)
        # logger.info(f"w3: {w3}")
        return gt, challenge, w3

    def click_verify(self, image, extra=None, verify_type="30103"):
        payload = {
            "image": base64.b64encode(image).decode(),
            "extra": 'click3',
            "token": self.token_ym,
            "type": verify_type
        }
        if extra:
            payload['extra'] = extra
        resp = requests.post("http://api.jfbym.com/api/YmServer/customApi", headers=self._headers,
                             data=json.dumps(payload))
        return resp.json()['data']['data']

    def geetest_click(self, click_xy):
        click_point_array = click_xy.split('|')
        click_point_true = []
        for item in click_point_array:
            x, y = item.split(',')
            point = str(int(int(x) / 344 * 10000)) + '_' + str(int(int(y) / 344 * 10000))
            click_point_true.append(point)
        click_true_str = ','.join(click_point_true)
        return click_true_str

    def YanZhengMa(self, gt, challenge, w3):
        params = {
            "gt": gt,
            "challenge": challenge,
            "lang": "zh-cn",
            "pt": "0",
            "client_type": "web",
            "w": w3,
        }
        url = "https://api.geevisit.com/ajax.php"
        time.sleep(random.randint(2, 3))
        res = requests.get(url, params=params, headers=self.headers)
        logger.info(res.text)
        if "validate" in res.text:
            logger.success(
                "验证成功, validate is {}".format(re.findall(r'"validate": "(.*)", "score"', res.text)[0]))
            # exit(0)

    def task_sequence(self):
            gt, challenge = self.register_page()
            self.gettype(gt)
            self.getPhp(gt, challenge)
            gt, challenge, w3 = self.get_php_Second(gt, challenge)
            self.YanZhengMa(gt, challenge, w3)

    def main(self):
        self.read_js()
        tasks = []
        with ProcessPoolExecutor(max_workers=3) as executor:
            for _ in range(20):
                tasks.append(executor.submit(self.task_sequence))

        for task in tasks:
            task.result()


if __name__ == '__main__':
    geetest = Geetest()
    geetest.main()
